﻿// /********************************************************
// *                                                       *
// *   Copyright (C) Microsoft. All rights reserved.       *
// *                                                       *
// ********************************************************/

using System.Data;
using System.Data.SqlClient;
using System;

namespace TelemetryService
{
    public static class DbUtility
    {
        private static int s_dataBufferLength = 17;

        public static DataTable CreatePerformanceMemoryTable()
        {
            DataTable table = new DataTable();

            table.Columns.Add("Id", typeof(int));

            table.Columns.Add("ComputerName", typeof(string));
            table.Columns.Add("ServerName", typeof(string));
            table.Columns.Add("UserAlias", typeof(string));
            table.Columns.Add("UserDomain", typeof(string));
            table.Columns.Add("UserSid", typeof(string));
            table.Columns.Add("ProcessName", typeof(string));
            table.Columns.Add("ProcessId", typeof(int));
            table.Columns.Add("ThreadNumber", typeof(int));
            table.Columns.Add("TelemetrySession", typeof(string));
            table.Columns.Add("ApplicationSession", typeof(string));
            table.Columns.Add("Timestamp", typeof(DateTime));
            table.Columns.Add("ActionGroupName", typeof(string));
            table.Columns.Add("Action", typeof(string));
            table.Columns.Add("ModuleName", typeof(string));
            table.Columns.Add("SensorName", typeof(string));
            table.Columns.Add("SensorValue", typeof(string));

            return table;
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public static void BulkDatabaseSaveInTransaction(SqlConnection destinationConnection, DataTable data)
        {
            if (destinationConnection != null && destinationConnection.State == ConnectionState.Open)
            {
                using (SqlTransaction transaction =
                    destinationConnection.BeginTransaction())
                {
                    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(
                        destinationConnection, SqlBulkCopyOptions.Default,
                        transaction))
                    {
                        bulkCopy.BatchSize = 10;
                        bulkCopy.DestinationTableName = "dbo.RawData";

                        try
                        {
                            bulkCopy.WriteToServer(data);
                            transaction.Commit();
                        }
                        catch (Exception)
                        {
                            transaction.Rollback();
                        }

                    }
                }

            }
            else
            {
                DbUtility.BulkDatabaseSaveInTransaction(GetConnectionString(), data);
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public static void BulkDatabaseSaveInTransaction(string connectionString, DataTable data)
        {
            using (SqlConnection destinationConnection = new SqlConnection(connectionString))
            {
                destinationConnection.Open();

                using (SqlTransaction transaction = destinationConnection.BeginTransaction())
                {
                    using (SqlBulkCopy bulkCopy = new SqlBulkCopy(
                               destinationConnection, SqlBulkCopyOptions.Default,
                               transaction))
                    {
                        bulkCopy.BatchSize = 10;
                        bulkCopy.DestinationTableName = "dbo.RawData";

                        try
                        {
                            bulkCopy.WriteToServer(data);
                            transaction.Commit();
                        }
                        catch (Exception)
                        {
                            transaction.Rollback();
                        }

                    }
                }
            }
        }

        public static string GetConnectionString()
        {
            return "Data Source=(local); " +
                " Integrated Security=true;" +
                "Initial Catalog=QETelemetry;";
        }

        public static string[] SplitWcfSessionId(string sessionId)
        {
            string uuidString = sessionId.Replace("uuid:", String.Empty);
            string[] sessionArray = new string[] { uuidString, String.Empty };
            if (uuidString.Length != sessionId.Length)
            {
                string[] stringSeparators = new string[] { ";id=" };
                sessionArray = uuidString.Split(stringSeparators, StringSplitOptions.None);
            }

            return sessionArray;
        }

        public static object[] ConvertToObjects(string[] data, string sessionId)
        {
            object[] array = new object[data.Length + 1];
            array[0] = System.DBNull.Value;

            Array.Copy(data, 0, array, 1, 8);

            array[9] = sessionId;

            Array.Copy(data, 8, array, 9, 7);

            return array;
        }

        public static object[] ConvertToObjects(MarkerStamp data, string telemetrySession)
        {
            object[] array = new object[s_dataBufferLength];
            array[0] = System.DBNull.Value;

            array[1] = data.ComputerName;
            array[2] = data.ServerName;
            array[3] = data.UserAlias;
            array[4] = data.UserDomain;
            array[5] = data.UserSid;
            array[6] = data.ProcessName;
            array[7] = data.ProcessId;
            array[8] = data.ThreadNumber;

            array[9] = telemetrySession;

            array[10] = data.ApplicationSession;
            array[11] = data.Timestamp;
            array[12] = data.ActionGroupName;
            array[13] = data.Action;
            array[14] = data.ModuleName;
            array[15] = data.SensorName;
            array[16] = data.SensorValue;

            return array;
        }

    }
}
